﻿/*
 * Last review by   : Yaser
 * Last review date : JUL-20-09
 */
using System;

namespace ERP.Business.DataTypes.BaseTypes
{
    /// <summary>
    /// Base class for all types
    /// </summary>
    [Serializable]
    [System.Runtime.Serialization.DataContract]
    [System.Runtime.Serialization.KnownType(typeof(BaseType))]
    public abstract class BaseType : IBaseType
    {
        #region Construcors

        /// <summary>
        /// Default constructor : initiate ID with GUID value
        /// </summary>
        public BaseType() : this(Guid.Empty, BaseTypes.DirtyFlag.None) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseType"/> class.
        /// </summary>
        /// <param name="id">The id.</param>
        public BaseType(Guid id) : this(id, DirtyFlag.None) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseType"/> class.
        /// </summary>
        /// <param name="dirtyFlag">The dirty flag.</param>
        public BaseType(DirtyFlag dirtyFlag) : this(Guid.Empty, dirtyFlag) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseType"/> class.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="dirtyFlag">The dirty flag.</param>
        public BaseType(Guid id, DirtyFlag dirtyFlag)
        {
            ID = id;
            DirtyFlag = dirtyFlag;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the ID.
        /// </summary>
        /// <value>The ID.</value>
        [System.Runtime.Serialization.DataMember]
        public Guid ID
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the dirty flag.
        /// </summary>
        /// <value>The dirty flag.</value>
        [System.Runtime.Serialization.DataMember]
        public DirtyFlag DirtyFlag
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public virtual bool Equals(object obj)
        {
            if (Compare(this, obj) == 0)
                return true;
            return false;
        }

        /// <summary>
        /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>
        /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than <paramref name="obj"/>. Zero This instance is equal to <paramref name="obj"/>. Greater than zero This instance is greater than <paramref name="obj"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// 	<paramref name="obj"/> is not the same type as this instance. </exception>
        public virtual int CompareTo(object obj)
        {
            return Compare(this, obj);
        }

        /// <summary>
        /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
        /// </summary>
        /// <param name="x">The first object to compare.</param>
        /// <param name="y">The second object to compare.</param>
        /// <returns>
        /// A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/>, as shown in the following table.Value Meaning Less than zero <paramref name="x"/> is less than <paramref name="y"/>. Zero <paramref name="x"/> equals <paramref name="y"/>. Greater than zero <paramref name="x"/> is greater than <paramref name="y"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">Neither <paramref name="x"/> nor <paramref name="y"/> implements the <see cref="T:System.IComparable"/> interface.-or- <paramref name="x"/> and <paramref name="y"/> are of different types and neither one can handle comparisons with the other. </exception>
        public virtual int Compare(object x, object y)
        {
            if (ERP.Framework.Components.Utilities.ComparingHelper.ComapringManager.CompareTypes(x, y) && x is IBaseType && y is IBaseType)
                return (x as IBaseType).ID.CompareTo((y as IBaseType).ID);
            throw new ArgumentException("Invalid object/objects type");
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public virtual object Clone()
        {
            return ERP.Framework.Components.Utilities.CloningHelper.CloningHelper.Clone(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposeManagedResources"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        public void Dispose(bool disposeManagedResources)
        {
            Dispose(true);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}